#include "head.h"
#include <asm-generic/socket.h>
#include <iostream>
#include <sys/socket.h>

using std::cout;
using std::endl;

//接收确定的length个字节数的函数
int recvn(int sockfd, void * buff, int length)
{
    int left = length; 
    char * pbuf = (char*)buff;
    int ret = 0;
    while(left > 0) {
        ret = recv(sockfd, pbuf, left, 0);
        pbuf += ret;
        left -= ret;
    }
    return length - left;
}

int main()
{
    //1. 创建监听套接字
    int sfd = socket(AF_INET, SOCK_STREAM, 0);
    cout << "sfd:" << sfd << endl;
    ERROR_CHECK(sfd, -1, "socket");

    //设置套接字的属性
    int on = 1;
    int ret = 0;
    //将网络地址设置为可以重用的
    ret = setsockopt(sfd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));
    ERROR_CHECK(ret, -1, "setsockopt");

    //ubuntu可以在系统层面提供负载均衡, 同时启动多个服务器进程
    ret = setsockopt(sfd, SOL_SOCKET, SO_REUSEPORT, &on, sizeof(on));
    ERROR_CHECK(ret, -1, "setsockopt");
    
    //2. 服务器绑定网络地址
    struct sockaddr_in serveraddr;
    memset(&serveraddr, 0, sizeof(serveraddr));
    serveraddr.sin_family = AF_INET;
    serveraddr.sin_port = htons(8000);
    serveraddr.sin_addr.s_addr = inet_addr("192.168.30.129");

    ret = bind(sfd, 
        (const struct sockaddr*)&serveraddr, sizeof(serveraddr));
    ERROR_CHECK(ret, -1, "bind");

    //3. 进行监听
    ret = listen(sfd, 1);
    cout << "server is listening.\n";

    while(1)
    {
        int newFd = accept(sfd, NULL, NULL);
        cout << "111, newFd:" << newFd << endl;
        ERROR_CHECK(newFd, -1, "accept");

        char buff[1024] = {0};
        ret = recv(newFd, buff, sizeof(buff), 0);
        cout << "recv ret:" << ret << endl;
        if(ret == 0) {
            //这意味着该连接已经断开了
            cout << "byebye" << endl;
            close(newFd);
            continue;
        }

        cout << "recv from client: " << buff << endl;
    }

    close(sfd);
    return 0;
}
